package com.heu.blood.match.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heu.blood.common.Constant.ConstantData;
import com.heu.blood.common.aop.ServiceLogAnnotation;
import com.heu.blood.common.commponent.DictBloodProductLoader;
import com.heu.blood.common.commponent.DictionaryLoader;
import com.heu.blood.common.utils.PageUtils;
import com.heu.blood.common.utils.Query;
import com.heu.blood.globalExceptionHandler.MyException;
import com.heu.blood.match.dao.BloodInformationDao;
import com.heu.blood.match.dao.BloodMatchDao;
import com.heu.blood.match.dictenum.*;
import com.heu.blood.match.dto.req.BloodInformationQueryPageReqDTO;
import com.heu.blood.match.entity.BloodInformationEntity;
import com.heu.blood.match.entity.BloodMatchEntity;
import com.heu.blood.match.entity.BloodStateInfoEntity;
import com.heu.blood.match.exception.QueryBloodInformationException;
import com.heu.blood.match.exception.TimeException;
import com.heu.blood.match.listener.ImportDataListenerForBloodinformation;
import com.heu.blood.match.service.BloodInformationService;
import com.heu.blood.match.vo.BloodInformationEntityVo;
import com.heu.blood.match.vo.BloodInformationIdHistoryVo;
import com.heu.blood.match.vo.BloodInventoryResultVo;
import com.heu.blood.match.vo.InventoryQueryVo;
import com.heu.blood.recycle.dao.BloodReturnDao;
import com.heu.blood.recycle.dictenum.BloodReturnReasonEnum;
import com.heu.blood.recycle.dictenum.BloodReturnVerifyStateEnum;
import com.heu.blood.recycle.entity.BloodReturnEntity;
import com.heu.blood.send.dao.BloodSendDao;
import com.heu.blood.send.entity.BloodSendEntity;
import com.heu.blood.statistic.entity.BloodStoreCountABO;
import com.heu.blood.statistic.entity.BloodStoreCountType;
import com.heu.blood.storge.dao.BloodInStorgeDao;
import com.heu.blood.storge.dao.BloodScrapDao;
import com.heu.blood.storge.dao.BloodVerifyStorgeDao;
import com.heu.blood.storge.entity.BloodInStorgeEntity;
import com.heu.blood.storge.entity.BloodScrapEntity;
import com.heu.blood.storge.entity.BloodVerifyStorgeEntity;
import com.heu.blood.storge.vo.BloodDeleteReturnVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import static com.heu.blood.common.enums.BloodInformationEnum.BLOOD_IN_MATCH;
import static com.heu.blood.common.enums.BloodInformationEnum.BLOOD_IN_STOCK;
import static com.heu.blood.common.enums.BloodStorgeEnum.*;
import static com.heu.blood.common.enums.CommonEnum.IF_SHOW;
import static com.heu.blood.common.enums.CommonEnum.IS_NOT_TEST_FLAG;


@Slf4j
@Service("bloodInformationService")
public class BloodInformationServiceImpl extends ServiceImpl<BloodInformationDao, BloodInformationEntity> implements BloodInformationService {

//    private final Logger log = LoggerFactory.getLogger("BloodInformation");


    @Autowired
    private BloodInformationDao bloodInformationDao;
    @Autowired
    private DictionaryLoader dictionaryLoader;
    @Autowired
    private ImportDataListenerForBloodinformation importDataListener;
    @Autowired
    private BloodInStorgeDao bloodInStorgeDao;
    @Autowired
    private BloodMatchDao bloodMatchDao;
    @Autowired
    private BloodScrapDao bloodScrapDao;
    @Autowired
    private BloodSendDao bloodSendDao;
    @Autowired
    private BloodReturnDao bloodReturnDao;
    @Autowired
    private BloodVerifyStorgeDao bloodVerifyStorgeDao;
    @Autowired
    private ExecutorService executor;
    @Autowired
    private DictBloodProductLoader dictBloodProductLoader;
    @Override
    public PageUtils queryPage(BloodInformationQueryPageReqDTO requestParam) {

        LambdaQueryWrapper<BloodInformationEntity> queryWrapper = Wrappers.lambdaQuery(BloodInformationEntity.class)
                .like(Strings.isNotBlank(requestParam.getBloodId()), BloodInformationEntity::getBloodId, requestParam.getBloodId())
                .in(requestParam.getAboBloodType() != null && requestParam.getAboBloodType().length != 0, BloodInformationEntity::getAboBloodType, requestParam.getAboBloodType())
                .eq(Strings.isNotBlank(requestParam.getRhBloodType()), BloodInformationEntity::getRhBloodType, requestParam.getRhBloodType())
                .eq(Strings.isNotBlank(requestParam.getBloodType()), BloodInformationEntity::getBloodType, requestParam.getBloodType())
                .eq(Strings.isNotBlank(requestParam.getBloodState()), BloodInformationEntity::getBloodState, requestParam.getBloodState())
                .eq(Strings.isNotBlank(requestParam.getBloodDonationCode()), BloodInformationEntity::getBloodDonationCode, requestParam.getBloodDonationCode())
                .ge(Strings.isNotBlank(requestParam.getStartTime()), BloodInformationEntity::getGmtCreate, requestParam.getStartTime())
                .le(Strings.isNotBlank(requestParam.getEndTime()), BloodInformationEntity::getGmtCreate, requestParam.getEndTime())
                .eq(Strings.isNotBlank(requestParam.getBatchNumber()), BloodInformationEntity::getBatchNumber, requestParam.getBatchNumber())
                .eq(BloodInformationEntity::getIfShow, IF_SHOW.code())
                //.like(Strings.isNotBlank(requestParam.getBatchNumber()),BloodInformationEntity::getBatchNumber,requestParam.getBatchNumber())
                .like(Strings.isNotBlank(requestParam.getBloodCenterDeliveryId()),BloodInformationEntity::getBloodCenterDeliveryId,requestParam.getBloodCenterDeliveryId())
                .eq(Strings.isNotBlank(requestParam.getMeasurementUnit()),BloodInformationEntity::getMeasurementUnit,requestParam.getMeasurementUnit())
                .eq(requestParam.getBloodCount() != null, BloodInformationEntity::getBloodCount,requestParam.getBloodCount());
//        String source = requestParam.getSource();
//        if (StringUtils.isNotBlank(source)) {
//            if (!"bloodbaglife".equals(source)) {
//                queryWrapper.eq(BloodInformationEntity::getBloodState, BloodStateEnum.IN_STOCK.code());
//            }
//        } else {
//            // 如果没传 source，默认加限制（或默认不加，视你的业务定）
//            queryWrapper.eq(BloodInformationEntity::getBloodState, BloodStateEnum.IN_STOCK.code());
//        }

        Map<String, Object> params = new HashMap<>();
        if (Strings.isNotBlank(requestParam.getBloodId())){
            params.put("bloodId", requestParam.getBloodId());
        }
        if (Strings.isNotBlank(requestParam.getBloodType())){
            params.put("bloodType", requestParam.getBloodType());
        }
        if (requestParam.getAboBloodType()!=null && requestParam.getAboBloodType().length != 0){
            params.put("aboBloodType", requestParam.getAboBloodType());
        }
        if (Strings.isNotBlank(requestParam.getRhBloodType())){
            params.put("rhBloodType", requestParam.getRhBloodType());
        }
        if (Strings.isNotBlank(requestParam.getBloodDonationCode())){
            params.put("bloodDonationCode", requestParam.getBloodDonationCode());
        }
        if (Strings.isNotBlank(requestParam.getBloodCenterDeliveryId())){
            params.put("bloodCenterDeliveryId", requestParam.getBloodCenterDeliveryId());
        }
        if (Strings.isNotBlank(requestParam.getStartTime())){
            params.put("startTime", requestParam.getStartTime());
        }
        if (Strings.isNotBlank(requestParam.getEndTime())){
            params.put("endTime", requestParam.getEndTime());
        }
        if (Strings.isNotBlank(requestParam.getBatchNumber())){
            params.put("batchNumber", requestParam.getBatchNumber());
        }
        if (Strings.isNotBlank(requestParam.getLimit())){
            params.put("limit", requestParam.getLimit());
        }
        if (Strings.isNotBlank(requestParam.getPage())){
            params.put("page", requestParam.getPage());
        }


        String sortField = requestParam.getSortField();
        if (Strings.isNotBlank(sortField)) {
            switch (sortField) {
                case "bloodId":
                    queryWrapper.orderByAsc(BloodInformationEntity::getBloodId);
                    break;
                case "bloodType":
                    queryWrapper.orderByAsc(BloodInformationEntity::getBloodType);
                    break;
                case "aboBloodType":
                    queryWrapper.orderByAsc(BloodInformationEntity::getAboBloodType);
                    break;
                case "rhBloodType":
                    queryWrapper.orderByAsc(BloodInformationEntity::getRhBloodType);
                    break;
                case "bloodState":
                    queryWrapper.orderByAsc(BloodInformationEntity::getBloodState);
                    break;
                case "bloodDonationCode":
                    queryWrapper.orderByAsc(BloodInformationEntity::getBloodDonationCode);
                    break;
                case "gmtCreate":
                    queryWrapper.orderByAsc(BloodInformationEntity::getGmtCreate);
                    break;
//                case "batchNumber":
//                    queryWrapper.orderByAsc(BloodInformationEntity::getBatchNumber);
//                    break;
                case "bloodCenterDeliveryId":
                    queryWrapper.orderByAsc(BloodInformationEntity::getBloodCenterDeliveryId);
                    break;
                case "measurementUnit":
                    queryWrapper.orderByAsc(BloodInformationEntity::getMeasurementUnit);
                    break;
                case "bloodCount":
                    queryWrapper.orderByAsc(BloodInformationEntity::getBloodCount);
                    break;
                case "batchNumber":
                    queryWrapper.orderByAsc(BloodInformationEntity::getBatchNumber);
                    break;
                default:
                    // 不合法字段默认按创建时间倒序
                    queryWrapper.orderByDesc(BloodInformationEntity::getGmtCreate);
            }
        } else {
            // 未指定排序字段，默认按创建时间倒序
            queryWrapper.orderByDesc(BloodInformationEntity::getGmtCreate);
        }

        // 根据进入表格倒序排列
        //queryWrapper.orderByDesc(BloodInformationEntity::getGmtCreate);
        IPage<BloodInformationEntity> page = this.page(
                new Query<BloodInformationEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }

    /**
     * 查询血液信息
     * @param
     * @return
     */
    @Override
    public List<BloodInformationEntity> query(BloodInformationEntityVo bloodInformationEntityVo) {
        // 构造queryWrapper对象
        LambdaQueryWrapper<BloodInformationEntity> queryWrapper = new LambdaQueryWrapper<>();
        // 添加过滤条件
        queryWrapper.eq(Strings.isNotBlank(bloodInformationEntityVo.getBloodId()), BloodInformationEntity::getBloodId, bloodInformationEntityVo.getBloodId())
                .eq(Strings.isNotBlank(bloodInformationEntityVo.getAboBloodType()), BloodInformationEntity::getAboBloodType, bloodInformationEntityVo.getAboBloodType())
                .eq(Strings.isNotBlank(bloodInformationEntityVo.getRhBloodType()), BloodInformationEntity::getRhBloodType, bloodInformationEntityVo.getRhBloodType())
                .eq(Strings.isNotBlank(bloodInformationEntityVo.getBloodType()), BloodInformationEntity::getBloodType, bloodInformationEntityVo.getBloodType())
                .eq(Strings.isNotBlank(bloodInformationEntityVo.getBloodState()), BloodInformationEntity::getBloodState, bloodInformationEntityVo.getBloodState())
                .eq(Strings.isNotBlank(bloodInformationEntityVo.getBloodCount().toString()), BloodInformationEntity::getBloodCount, bloodInformationEntityVo.getBloodCount())
                .eq(Strings.isNotBlank(bloodInformationEntityVo.getMeasurementUnit()), BloodInformationEntity::getMeasurementUnit, bloodInformationEntityVo.getMeasurementUnit())
                .eq(Strings.isNotBlank(bloodInformationEntityVo.getBloodDonationCode()), BloodInformationEntity::getBloodDonationCode, bloodInformationEntityVo.getBloodDonationCode())
                .le(bloodInformationEntityVo.getStartTime() != null, BloodInformationEntity::getCollectTime, bloodInformationEntityVo.getCollectTime())
                .ge(bloodInformationEntityVo.getFailureTime() != null,BloodInformationEntity::getFailureTime, bloodInformationEntityVo.getFailureTime())
                .eq(BloodInformationEntity::getIfShow, IF_SHOW.code());
        // 根据失效时间升序排列
        queryWrapper.orderByAsc(BloodInformationEntity::getFailureTime);
        return bloodInformationDao.selectList(queryWrapper);
    }

    /**
     * 根据血液id查询血液信息
     * @param bloodId
     * @return
     */
    @Override
    @ServiceLogAnnotation(module = "血液信息", operate = "根据血液id查询血液信息")
    public BloodInformationEntity queryByBloodId(String bloodId) {

        // 构造条件构造器对象
        LambdaQueryWrapper<BloodInformationEntity> queryWrapper = new LambdaQueryWrapper<>();
        // 添加过滤条件
        queryWrapper.eq(Strings.isNotBlank(bloodId), BloodInformationEntity::getBloodId, bloodId)
                    .eq(BloodInformationEntity::getIfShow, IF_SHOW.code());
        // 根据失效时间升序排列
        queryWrapper.orderByAsc(BloodInformationEntity::getFailureTime);
        log.info("查询到的血液信息：");
        return bloodInformationDao.selectOne(queryWrapper);
    }

    @Override
    public List<BloodInformationEntity> queryListByBloodId(String bloodId) {
        LambdaQueryWrapper<BloodInformationEntity> queryWrapper = new LambdaQueryWrapper<>();
        // 添加过滤条件
        queryWrapper.eq(Strings.isNotBlank(bloodId), BloodInformationEntity::getBloodId, bloodId);

        return bloodInformationDao.selectList(queryWrapper);
    }

    @Override
    public BloodInformationEntity InsertOneBloodInformationData(BloodInformationEntity bloodInformationEntity) {
        // 生成一个bloodinformation对象
        BloodInformationEntity bloodInformation = new BloodInformationEntity();
        // 添加bloodId
        if (Strings.isNotBlank(bloodInformationEntity.getBloodId())){
            bloodInformation.setBloodId(bloodInformationEntity.getBloodId());
        }
        // 添加barcode
        if (Strings.isNotBlank(String.valueOf(bloodInformationEntity.getBarcode()))){
            bloodInformation.setBarcode(bloodInformationEntity.getBarcode());
        }
        // 添加extendCode
        if (Strings.isNotBlank(bloodInformationEntity.getExtendCode())){
            bloodInformation.setExtendCode(bloodInformationEntity.getExtendCode());
        }
        // 添加blood_type
        if (Strings.isNotBlank(bloodInformationEntity.getBloodType())){
            bloodInformation.setBloodType(bloodInformationEntity.getBloodType());
        }
        // 添加blood_count
        if (Strings.isNotBlank(String.valueOf(bloodInformationEntity.getBloodCount()))){
            bloodInformation.setBloodCount(bloodInformationEntity.getBloodCount());
        }
        //添加ABO血型
        if(Strings.isNotBlank(bloodInformationEntity.getAboBloodType())){
            bloodInformation.setAboBloodType(bloodInformationEntity.getAboBloodType());
        }
        //添加RH血型
        if(Strings.isNotBlank(bloodInformationEntity.getRhBloodType())){
            bloodInformation.setRhBloodType(bloodInformationEntity.getRhBloodType());
        }
        //设置血液来源
        if(Strings.isNotBlank(String.valueOf(bloodInformationEntity.getBloodSource()))){
            bloodInformation.setBloodSource(bloodInformationEntity.getBloodSource());
        }
        //添加失效时间
        if(Strings.isNotBlank(String.valueOf(bloodInformationEntity.getFailureTime()))){
            bloodInformation.setFailureTime(bloodInformationEntity.getFailureTime());
        }
        //添加采集时间
        if(Strings.isNotBlank(String.valueOf(bloodInformationEntity.getCollectTime()))){
            bloodInformation.setCollectTime(bloodInformationEntity.getCollectTime());
        }
        //添加入库金额
        if(Strings.isNotBlank(String.valueOf(bloodInformationEntity.getInboundPrice()))){
            bloodInformation.setInboundPrice(bloodInformationEntity.getInboundPrice());
        }
        //添加血袋位置
        if(Strings.isNotBlank(bloodInformationEntity.getBloodLocation())){
            bloodInformation.setBloodLocation(bloodInformationEntity.getBloodLocation());
        }
        //添加血液金额
        if(Strings.isNotBlank(String.valueOf(bloodInformationEntity.getBloodPrice()))){
            bloodInformation.setBloodPrice(bloodInformationEntity.getBloodPrice());
        }
        //添加计量单位
        if(Strings.isNotBlank(bloodInformationEntity.getMeasurementUnit())){
            bloodInformation.setMeasurementUnit(bloodInformationEntity.getMeasurementUnit());
        }
        //添加批次号
        if(Strings.isNotBlank(String.valueOf(bloodInformationEntity.getBatchNumber()))){
            bloodInformation.setBatchNumber(bloodInformationEntity.getBatchNumber());
        }
        //添加献血时编号
        if(Strings.isNotBlank(bloodInformationEntity.getBloodDonationCode())){
            bloodInformation.setBloodDonationCode(bloodInformationEntity.getBloodDonationCode());
        }
        //添加血库出战编号
        if(Strings.isNotBlank(bloodInformationEntity.getBloodBankDeliveryId())){
            bloodInformation.setBloodBankDeliveryId(bloodInformationEntity.getBloodBankDeliveryId());
        }
        //添加院区
        if(Strings.isNotBlank(bloodInformationEntity.getHospitalClassification())){
            bloodInformation.setHospitalClassification(bloodInformationEntity.getHospitalClassification());
        }

        //上面都检验完了之后设置血液状态
        bloodInformation.setBloodState(INSERT_STORGE_SUCCESS.code());
        //设置血液信息的test_flag
        bloodInformation.setTestFlag(Integer.valueOf(IS_NOT_TEST_FLAG.code()));
        //返回封装的对象
        return bloodInformation;

    }

    @Override
    public BloodInformationEntity convertFromMapToEntity(Map bloodInformationMap) {
        log.info(String.valueOf(bloodInformationMap));
        Map<String,String> subDict = dictionaryLoader.getSubDict();
        BloodInformationEntity bloodInformationEntity = new BloodInformationEntity();
        if (bloodInformationMap.size() != 0){//解析成功
                if(bloodInformationMap.get("bloodId") != null)
                    bloodInformationEntity.setBloodId((String) bloodInformationMap.get("bloodId"));
                if(bloodInformationMap.get("barcode") != null) {
                    log.info(String.valueOf(bloodInformationMap.get("barcode")));
                    bloodInformationEntity.setBarcode(String.valueOf(bloodInformationMap.get("barcode")));
                }
                if(bloodInformationMap.get("extendCode") != null)
                    bloodInformationEntity.setExtendCode((String) bloodInformationMap.get("extendCode"));
                if(bloodInformationMap.get("bloodType") != null){
                    String newBloodType = subDict.get((String) bloodInformationMap.get("bloodType"));
                    bloodInformationEntity.setBloodType(newBloodType);
                }
                if(bloodInformationMap.get("bloodCount") != null){
                    log.info("----------------------------------");
                   log.info(String.valueOf(new BigDecimal(String.valueOf(bloodInformationMap.get("bloodCount")))));
                    bloodInformationEntity.setBloodCount(new BigDecimal(String.valueOf(bloodInformationMap.get("bloodCount"))));
                }
                if(bloodInformationMap.get("aboBloodType") != null){
                    String newAboBloodType = subDict.get((String) bloodInformationMap.get("aboBloodType"));
                    bloodInformationEntity.setAboBloodType(newAboBloodType);
                }
                if(bloodInformationMap.get("rhBloodType") != null){
                    String newRhBloodType = (String) bloodInformationMap.get("rhBloodType");
                    bloodInformationEntity.setRhBloodType(newRhBloodType);
                }
                //时间格式已经转换成yyyy-MM-dd
                if(bloodInformationMap.get("failureTime") != null){
                    bloodInformationEntity.setFailureTime(java.sql.Date.valueOf(String.valueOf(bloodInformationMap.get("failureTime"))));
                }
                if(bloodInformationMap.get("collectTime") != null){
                    bloodInformationEntity.setCollectTime(java.sql.Date.valueOf(String.valueOf(bloodInformationMap.get("collectTime"))));
                }
                if(bloodInformationMap.get("bloodSource") != null){
                    String newBloodSource = subDict.get((String) bloodInformationMap.get("bloodSource"));
                    bloodInformationEntity.setBloodSource(newBloodSource);
                }
                if(bloodInformationMap.get("inboundPrice") != null)
                    bloodInformationEntity.setInboundPrice(new BigDecimal(String.valueOf(bloodInformationMap.get("inboundPrice"))));
                if(bloodInformationMap.get("bloodLocation") != null){
                    String newBloodLocation = subDict.get((String) bloodInformationMap.get("bloodLocation"));
                    bloodInformationEntity.setBloodLocation(newBloodLocation);
                }
                if(bloodInformationMap.get("bloodPrice") != null)
                    bloodInformationEntity.setBloodPrice(new BigDecimal(String.valueOf(bloodInformationMap.get("bloodPrice"))));
                if(bloodInformationMap.get("measurementUnit") != null){
                    String newMeasurementUnit = subDict.get((String) bloodInformationMap.get("measurementUnit"));
                    bloodInformationEntity.setMeasurementUnit(newMeasurementUnit);
                }
                if(bloodInformationMap.get("batchNumber") != null){
                    double doubleValue = Double.parseDouble(String.valueOf(bloodInformationMap.get("batchNumber")));
                    long longValue = (long) doubleValue;
                    bloodInformationEntity.setBatchNumber(longValue);
                }
                if(bloodInformationMap.get("bloodDonationCode") != null)
                    bloodInformationEntity.setBloodDonationCode((String) bloodInformationMap.get("bloodDonationCode"));
                if(bloodInformationMap.get("bloodBankDeliveryId") != null)
                    bloodInformationEntity.setBloodBankDeliveryId((String) bloodInformationMap.get("bloodBankDeliveryId"));
                if(bloodInformationMap.get("hospitalClassification") != null){
                    String newhospitalClassification = subDict.get((String) bloodInformationMap.get("hospitalClassification"));
                    bloodInformationEntity.setHospitalClassification(newhospitalClassification);
                }
                bloodInformationEntity.setTestFlag(Integer.valueOf(IS_NOT_TEST_FLAG.code()));
                bloodInformationEntity.setBloodState(INSERT_STORGE_SUCCESS.code());//初始化血液状态
        }
        return bloodInformationEntity;
    }

    @Override
    public List<BloodStoreCountType> selectBloodTypeCount() {
        return bloodInformationDao.selectBloodTypeCount();
    }

    @Override
    public List<BloodStoreCountABO> selectAboTypeCount() {
        return bloodInformationDao.selectAboTypeCount();
    }

    @Override
    public void importExcel(MultipartFile multipartFile) {
        InputStream inputStream = null;
        try {
            inputStream = multipartFile.getInputStream();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
        EasyExcel.read(inputStream, BloodInformationEntity.class, importDataListener).sheet().doRead();
    }

    @Override
    public List<BloodInformationEntity> searchMatchBlood(BloodInformationEntity bloodInformationEntity) {
        // 构造queryWrapper对象
        LambdaQueryWrapper<BloodInformationEntity> queryWrapper = new LambdaQueryWrapper<>();
        // 添加过滤条件
        queryWrapper.eq(Strings.isNotBlank(bloodInformationEntity.getAboBloodType()), BloodInformationEntity::getAboBloodType, bloodInformationEntity.getAboBloodType())
                .eq(Strings.isNotBlank(bloodInformationEntity.getRhBloodType()), BloodInformationEntity::getRhBloodType, bloodInformationEntity.getRhBloodType())
                .eq(Strings.isNotBlank(bloodInformationEntity.getBloodType()), BloodInformationEntity::getBloodType, bloodInformationEntity.getBloodType())
                .le(bloodInformationEntity.getBloodCount() != null, BloodInformationEntity::getBloodCount, bloodInformationEntity.getBloodCount())
                .eq(Strings.isNotBlank(bloodInformationEntity.getMeasurementUnit()), BloodInformationEntity::getMeasurementUnit, bloodInformationEntity.getMeasurementUnit())
                .ge(bloodInformationEntity.getFailureTime() != null,BloodInformationEntity::getFailureTime, bloodInformationEntity.getFailureTime())
                .in(BloodInformationEntity::getBloodState, Arrays.asList(BLOOD_IN_STOCK.code(), BLOOD_IN_MATCH.code()))
                .eq(BloodInformationEntity::getIfShow, IF_SHOW.code());
        // 根据失效时间升序排列
        queryWrapper.orderByAsc(BloodInformationEntity::getFailureTime);
        return bloodInformationDao.selectList(queryWrapper);
    }

    @Transactional
    @Override
    public void batchUpdateInStockStateByBloodId(String[] bloodids) {
        List<String> bloodidslist = Arrays.asList(bloodids);
        //更新血液信息表
        bloodInformationDao.batchUpdateStateForInStockByBloodId(bloodidslist, BLOOD_IN_STOCK_STATE.code());
        //更新血液入库表状态
        bloodInStorgeDao.BatchUpdateBloodStateForInstorge(bloodidslist,BLOOD_IN_STOCK_STATE.code());
    }
    @Transactional
    @Override
    public void batchUpdateBloodReturnStateByBloodId(String[] bloodids) {
        List<String> bloodidslist = Arrays.asList(bloodids);
        //更新血液信息表状态
        bloodInformationDao.batchUpdateStateForReturnByBloodId(bloodidslist, BLOOD_RETURN_TO_STATION.code());
        //更新血液入库表状态
        bloodInStorgeDao.BatchUpdateBloodStateForInstorge(bloodidslist,BLOOD_RETURN_TO_STATION.code());
    }


    @Override
    public boolean updateBloodStateByBloodId(String BloodId,String state) {
        //调用updatewrapper 进行血液更新
        LambdaUpdateWrapper<BloodInformationEntity> updateWapper = new LambdaUpdateWrapper<>();
        updateWapper.eq(Strings.isNotBlank(BloodId),BloodInformationEntity::getBloodId,BloodId);
        updateWapper.set(BloodInformationEntity::getBloodState,state);
        //记录结果
        int res = bloodInformationDao.update(null,updateWapper);
        //判断状态是否是否成功
        return res==1;
    }



    @Override
    public boolean updateTestFlagByBloodId(String BloodId) {
        //调用updatewrapper 进行血液更新
        LambdaUpdateWrapper<BloodInformationEntity> updateWapper = new LambdaUpdateWrapper<>();
        updateWapper.eq(Strings.isNotBlank(BloodId),BloodInformationEntity::getBloodId,BloodId);
        updateWapper.set(BloodInformationEntity::getTestFlag, IF_SHOW.code());
        //记录结果
        int res = bloodInformationDao.update(null,updateWapper);
        //判断状态是否是否成功
        return res==1;
    }

    @Override
    public BloodInformationIdHistoryVo getBloodInformationIdHistory(String bloodId) {
        BloodInformationIdHistoryVo bloodInformationIdHistoryVo = new BloodInformationIdHistoryVo();
        if (bloodId == null || "".equals(bloodId)) return null;


        List<BloodStateEnum> notScrapFlow = Arrays.asList(
                BloodStateEnum.IN_STORAGE_TEST,
                BloodStateEnum.IN_STOCK,
                BloodStateEnum.IN_MATCH,
                BloodStateEnum.BLOOD_ALREADY_SEND,
                BloodStateEnum.USED
        );

        List<BloodStateEnum> ScrapFlow = Arrays.asList(
                BloodStateEnum.IN_STORAGE_TEST,
                BloodStateEnum.IN_STOCK,
                BloodStateEnum.BLOOD_SCRAP
        );

        LambdaQueryWrapper<BloodInformationEntity> bloodInformationQuery = new LambdaQueryWrapper<>();
        bloodInformationQuery.eq(Strings.isNotBlank(bloodId), BloodInformationEntity::getBloodId, bloodId);
        BloodInformationEntity bloodInformation = bloodInformationDao.selectOne(bloodInformationQuery);
        String bloodType = bloodInformation.getBloodType();

        if (bloodInformation == null) return null;

        String currentState = bloodInformation.getBloodState();
        List<BloodStateInfoEntity> list = new ArrayList<>();

        if (BloodStateEnum.BLOOD_SCRAP.code().equals(currentState)) {//报废

            boolean isScrappedInStock = bloodVerifyStorgeDao.selectCount(
                    new LambdaQueryWrapper<BloodVerifyStorgeEntity>()
                            .eq(BloodVerifyStorgeEntity::getBloodId, bloodId)
            ) > 0;//判断是否在血液在库报废  大于0即在血液在库状态报废、为0即在入库检验报废

            List<BloodStateEnum> currentFlow = ScrapFlow;
            for (BloodStateEnum state : currentFlow) {
                BloodStateInfoEntity node = new BloodStateInfoEntity();
                node.setTitle(state.value());

                if (BloodStateEnum.IN_STORAGE_TEST.code().equals(state.code())) {
                    // 入库检验节点
                    node.setStatus(StateEnum.SUCCESS.value());
                    list.add(node);
                } else if (BloodStateEnum.IN_STOCK.code().equals(state.code())) {
                    // 血液在库节点
                    if (isScrappedInStock) {
                        node.setStatus(StateEnum.SUCCESS.value());
                    } else {
                        node.setStatus(StateEnum.WAIT.value()); // 血液在库置为WAIT
                    }
                    list.add(node);
                } else if (BloodStateEnum.BLOOD_SCRAP.code().equals(state.code())) {
                    // 已报废节点
                    node.setStatus(StateEnum.SUCCESS.value());
                    list.add(node);
                }
            }
        } else {
            boolean isCurrentStateFound = false;
            Map<String, String> dictCodeMap = dictBloodProductLoader.getchildToParent();
            boolean isWait = TypeEnum.FROZEN_PLASMA.value().equals(dictCodeMap.get(bloodType));

            System.out.println(isWait);
            System.out.println(currentState);
            System.out.println(bloodType);
            System.out.println(dictCodeMap.get(bloodType));
            System.out.println(TypeEnum.FROZEN_PLASMA.value());
            for (BloodStateEnum state : notScrapFlow) {
                BloodStateInfoEntity node = new BloodStateInfoEntity();
                node.setTitle(state.value());
                if (state.code().equals(currentState)) {
                        node.setStatus(StateEnum.SUCCESS.value());
                        isCurrentStateFound = true;
                } else if (!isCurrentStateFound) {
                        node.setStatus(StateEnum.SUCCESS.value());
                } else {
                        node.setStatus(StateEnum.WAIT.value());
                }
                if (BloodStateEnum.IN_MATCH.code().equals(state.code())) {
                        if (isWait) {
                            node.setStatus(StateEnum.WAIT.value());
                        }
                }
                list.add(node);
            }

            }
            bloodInformationIdHistoryVo.setBloodStateInfoEntity(list);

// 1.变量名2.querywrapper的实体3.eq里的实体4.dao中的selectOne5.set
            CompletableFuture<Void> bloodinstorgeFuture = CompletableFuture.runAsync(() -> {
                LambdaQueryWrapper<BloodInStorgeEntity> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Strings.isNotBlank(bloodId), BloodInStorgeEntity::getBloodId, bloodId);
                List<BloodInStorgeEntity> bloodInStorgeEntities = bloodInStorgeDao.selectList(queryWrapper);
                bloodInformationIdHistoryVo.setBloodInStorgeEntity(bloodInStorgeEntities);
            }, executor);

            CompletableFuture<Void> bloodinformationFuture = CompletableFuture.runAsync(() -> {
                LambdaQueryWrapper<BloodInformationEntity> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Strings.isNotBlank(bloodId), BloodInformationEntity::getBloodId, bloodId);
                List<BloodInformationEntity> bloodInformationEntities = bloodInformationDao.selectList(queryWrapper);
                bloodInformationIdHistoryVo.setBloodInformationEntity(bloodInformationEntities);
            }, executor);

            CompletableFuture<Void> bloodverifyFuture = CompletableFuture.runAsync(() -> {
                LambdaQueryWrapper<BloodVerifyStorgeEntity> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Strings.isNotBlank(bloodId), BloodVerifyStorgeEntity::getBloodId, bloodId);
                List<BloodVerifyStorgeEntity> bloodVerifyStorgeEntities = bloodVerifyStorgeDao.selectList(queryWrapper);
                bloodInformationIdHistoryVo.setBloodVerifyStorgeEntity(bloodVerifyStorgeEntities);
            }, executor);

            CompletableFuture<Void> matchFuture = CompletableFuture.runAsync(() -> {
                LambdaQueryWrapper<BloodMatchEntity> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Strings.isNotBlank(bloodId), BloodMatchEntity::getBloodId, bloodId);
                List<BloodMatchEntity> bloodMatchEntities = bloodMatchDao.selectList(queryWrapper);
                bloodInformationIdHistoryVo.setBloodMatchEntity(bloodMatchEntities);
            }, executor);

            CompletableFuture<Void> scrapFuture = CompletableFuture.runAsync(() -> {
                LambdaQueryWrapper<BloodScrapEntity> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Strings.isNotBlank(bloodId), BloodScrapEntity::getBloodId, bloodId);
                List<BloodScrapEntity> bloodScrapEntities = bloodScrapDao.selectList(queryWrapper);
                bloodInformationIdHistoryVo.setBloodScrapEntity(bloodScrapEntities);
            }, executor);

            CompletableFuture<Void> sendFuture = CompletableFuture.runAsync(() -> {
                LambdaQueryWrapper<BloodSendEntity> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Strings.isNotBlank(bloodId), BloodSendEntity::getBloodId, bloodId);
                List<BloodSendEntity> bloodSendEntities = bloodSendDao.selectList(queryWrapper);
                bloodInformationIdHistoryVo.setBloodSendEntity(bloodSendEntities);
            }, executor);

            CompletableFuture<Void> returnFuture = CompletableFuture.runAsync(() -> {
                LambdaQueryWrapper<BloodReturnEntity> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Strings.isNotBlank(bloodId), BloodReturnEntity::getBloodId, bloodId);
                List<BloodReturnEntity> bloodReturnEntities = bloodReturnDao.selectList(queryWrapper);
                bloodInformationIdHistoryVo.setBloodReturnEntity(bloodReturnEntities);
            }, executor);


            try {
                CompletableFuture.allOf(bloodinstorgeFuture,
                        bloodinformationFuture,
                        bloodverifyFuture,
                        matchFuture,
                        scrapFuture,
                        sendFuture,
                        returnFuture).get();
            } catch (Exception e) {
                e.printStackTrace();
            }

            return bloodInformationIdHistoryVo;
        }

//    @Override
//    public Map<String, Map<String, String>> getBloodInventory() {
//        LambdaQueryWrapper<BloodInformationEntity> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(BloodInformationEntity::getBloodState, BloodStateEnum.IN_STOCK.code());
//        List<BloodInformationEntity> bloodInformationEntities = bloodInformationDao.selectList(queryWrapper);
//
//        // 检查无库存血液
//        if (bloodInformationEntities == null || bloodInformationEntities.isEmpty()) {
//            throw new MyException(QueryBloodInformationException.NO_BLOOD_IN_STOCK);
//        }
//
//        // 外层Map使用TreeMap保持排序
//        Map<String, Map<String, String>> result = new TreeMap<>();
//
//        // 首先初始化所有血液类型的所有血型组合为"0"
//        bloodInformationEntities.stream()
//                .map(BloodInformationEntity::getBloodType)
//                .distinct()
//                .forEach(bloodType -> {
//                    Map<String, String> innerMap = new TreeMap<>();
//                    for (AboRhTypeEnum aboRhTypeEnum : AboRhTypeEnum.values()) {
//                        innerMap.put(aboRhTypeEnum.code(), "0");
//                    }
//                    result.put(bloodType, innerMap);
//                });
//
//        // 然后填充实际存在的数据
//        for (BloodInformationEntity bloodInformation : bloodInformationEntities) {
//            String bloodType = bloodInformation.getBloodType();
//            String aboBloodType = bloodInformation.getAboBloodType();
//            String rhBloodType = bloodInformation.getRhBloodType();
//            BigDecimal count = bloodInformation.getBloodCount();
//
//            if (StringUtils.isAnyBlank(bloodType, aboBloodType, rhBloodType) || count == null) {
//                continue; // 过滤掉不完整的数据
//            }
//
//            String aboRhType = aboBloodType + rhBloodType;
//            Map<String, String> innerMap = result.get(bloodType);
//
//            // 获取当前已有数量并累加
//            BigDecimal currentCount = new BigDecimal(innerMap.getOrDefault(aboRhType, "0"));
//            innerMap.put(aboRhType, currentCount.add(count).toString());
//        }
//
//        return result;
//    }


    @Override
    public BloodInventoryResultVo getBloodInventory(InventoryQueryVo inventoryQuery) {
        LambdaQueryWrapper<BloodInformationEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BloodInformationEntity::getBloodState, BloodStateEnum.IN_STOCK.code());
        if (inventoryQuery.getStartDate() != null
                && inventoryQuery.getEndDate() != null
                && inventoryQuery.getStartDate().after(inventoryQuery.getEndDate())) {
            throw new MyException(TimeException.TIME_OUTLINE);
        }
        if (inventoryQuery != null && inventoryQuery.getStartDate() != null && inventoryQuery.getEndDate() != null) {
            Calendar startCal = Calendar.getInstance();
            startCal.setTime(inventoryQuery.getStartDate());
            Calendar endCal = Calendar.getInstance();
            endCal.setTime(inventoryQuery.getEndDate());
            boolean sameDay = startCal.get(Calendar.YEAR) == endCal.get(Calendar.YEAR)
                    && startCal.get(Calendar.MONTH) == endCal.get(Calendar.MONTH)
                    && startCal.get(Calendar.DAY_OF_MONTH) == endCal.get(Calendar.DAY_OF_MONTH);
            if (sameDay) {
                endCal.set(Calendar.HOUR_OF_DAY, 23);
                endCal.set(Calendar.MINUTE, 59);
                endCal.set(Calendar.SECOND, 59);
                endCal.set(Calendar.MILLISECOND, 999);
                inventoryQuery.setEndDate(endCal.getTime());
            }
        }
        if (inventoryQuery.getStartDate() != null) {
            queryWrapper.ge(BloodInformationEntity::getGmtCreate, inventoryQuery.getStartDate());
        }
        if (inventoryQuery.getEndDate() != null) {
            queryWrapper.le(BloodInformationEntity::getGmtCreate, inventoryQuery.getEndDate());
        }
        if (inventoryQuery.getRhBloodTypes() != null && !inventoryQuery.getRhBloodTypes().isEmpty()) {
            queryWrapper.eq(BloodInformationEntity::getRhBloodType, inventoryQuery.getRhBloodTypes());
        }
        List<BloodInformationEntity> bloodList = bloodInformationDao.selectList(queryWrapper);

        Map<String, List<BloodInformationEntity>> typeGroup = bloodList.stream()
                .collect(Collectors.groupingBy(BloodInformationEntity::getBloodType));

        List<BloodInventoryResultVo.BloodInventoryBlock> quantityList = new ArrayList<>();
        List<BloodInventoryResultVo.BloodInventoryBlock> bagList = new ArrayList<>();

        // 局部初始化方法：用枚举初始化 ABO 血型 Map
        Supplier<Map<String, Integer>> initABOGroupMap = () -> {
            Map<String, Integer> map = new LinkedHashMap<>();
            for (AboBloodTypeEnum group : AboBloodTypeEnum.values()) {
                map.put(group.code(), 0);
            }
            return map;
        };

        for (Map.Entry<String, List<BloodInformationEntity>> typeEntry : typeGroup.entrySet()) {
            String bloodType = typeEntry.getKey();
            List<BloodInformationEntity> typeList = typeEntry.getValue();

            Map<BigDecimal, List<BloodInformationEntity>> specGroup = typeList.stream()
                    .collect(Collectors.groupingBy(BloodInformationEntity::getBloodCount));

            List<BloodInventoryResultVo.BloodInventorySpecRow> quantityRows = new ArrayList<>();
            List<BloodInventoryResultVo.BloodInventorySpecRow> bagRows = new ArrayList<>();

            Map<String, Integer> quantitySubtotalMap = initABOGroupMap.get();
            Map<String, Integer> bagSubtotalMap = initABOGroupMap.get();
            BigDecimal quantityTotalAmount = BigDecimal.ZERO;
            BigDecimal bagTotalAmount = BigDecimal.ZERO;

            for (Map.Entry<BigDecimal, List<BloodInformationEntity>> specEntry : specGroup.entrySet()) {
                BigDecimal spec = specEntry.getKey();
                List<BloodInformationEntity> specList = specEntry.getValue();

                List<BloodInventoryResultVo.RhGroupRow> quantityRhRows = new ArrayList<>();
                List<BloodInventoryResultVo.RhGroupRow> bagRhRows = new ArrayList<>();

                for (RhBloodTypeEnum rhEnum : RhBloodTypeEnum.values()) {
                    String rh = rhEnum.code();

                    Map<String, Integer> quantityMap = initABOGroupMap.get();
                    Map<String, Integer> bagMap = initABOGroupMap.get();

                    BigDecimal amountSum = BigDecimal.ZERO;

                    for (BloodInformationEntity entity : specList) {
                        if (!rh.equals(entity.getRhBloodType())) continue;
                        String group = entity.getAboBloodType();
                        BigDecimal price = entity.getBloodPrice() == null ? BigDecimal.ZERO : entity.getBloodPrice();

                        // 袋数统计
                        bagMap.put(group, bagMap.getOrDefault(group, 0) + 1);
                        amountSum = amountSum.add(price);
                    }

                    // 数量 = 袋数 × 规格
                    for (AboBloodTypeEnum groupEnum : AboBloodTypeEnum.values()) {
                        String group = groupEnum.code();
                        int bagCount = bagMap.getOrDefault(group, 0);
                        int quantity = bagCount * spec.intValue();
                        quantityMap.put(group, quantity);
                    }

                    // 数量行
                    BloodInventoryResultVo.RhGroupRow quantityRhRow = new BloodInventoryResultVo.RhGroupRow();
                    quantityRhRow.setRh(rh);
                    quantityRhRow.setQuantity(quantityMap);
                    quantityRhRow.setAmount(amountSum);
                    quantityRhRow.setComponentSubtotal(quantityMap.values().stream().mapToInt(i -> i).sum());
                    quantityRhRows.add(quantityRhRow);

                    // 袋数行
                    BloodInventoryResultVo.RhGroupRow bagRhRow = new BloodInventoryResultVo.RhGroupRow();
                    bagRhRow.setRh(rh);
                    bagRhRow.setQuantity(bagMap);
                    bagRhRow.setAmount(amountSum);
                    bagRhRow.setComponentSubtotal(bagMap.values().stream().mapToInt(i -> i).sum());
                    bagRhRows.add(bagRhRow);
                }

                // 累加 subtotal
                for (AboBloodTypeEnum groupEnum : AboBloodTypeEnum.values()) {
                    String group = groupEnum.code();
                    int subtotalQty = quantityRhRows.stream()
                            .mapToInt(r -> r.getQuantity().getOrDefault(group, 0))
                            .sum();
                    quantitySubtotalMap.put(group, quantitySubtotalMap.getOrDefault(group, 0) + subtotalQty);

                    int subtotalBag = bagRhRows.stream()
                            .mapToInt(r -> r.getQuantity().getOrDefault(group, 0))
                            .sum();
                    bagSubtotalMap.put(group, bagSubtotalMap.getOrDefault(group, 0) + subtotalBag);
                }

                // 规格金额累加
                BigDecimal quantitySpecAmount = quantityRhRows.stream()
                        .map(BloodInventoryResultVo.RhGroupRow::getAmount)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal bagSpecAmount = bagRhRows.stream()
                        .map(BloodInventoryResultVo.RhGroupRow::getAmount)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);

                quantityTotalAmount = quantityTotalAmount.add(quantitySpecAmount);
                bagTotalAmount = bagTotalAmount.add(bagSpecAmount);

                // 组装规格行
                BloodInventoryResultVo.BloodInventorySpecRow quantityRow = new BloodInventoryResultVo.BloodInventorySpecRow();
                quantityRow.setSpec(spec);
                quantityRow.setRhList(quantityRhRows);
                quantityRows.add(quantityRow);

                BloodInventoryResultVo.BloodInventorySpecRow bagRow = new BloodInventoryResultVo.BloodInventorySpecRow();
                bagRow.setSpec(spec);
                bagRow.setRhList(bagRhRows);
                bagRows.add(bagRow);
            }

            // 组装成分块
            BloodInventoryResultVo.BloodInventoryBlock quantityBlock = new BloodInventoryResultVo.BloodInventoryBlock();
            quantityBlock.setBloodType(bloodType);
            quantityBlock.setSpecRows(quantityRows);
            quantityBlock.setSubtotal(quantitySubtotalMap);
            quantityBlock.setAmount(quantityTotalAmount);
            quantityBlock.setComponentSubtotal(quantitySubtotalMap.values().stream().mapToInt(i -> i).sum());
            quantityList.add(quantityBlock);

            BloodInventoryResultVo.BloodInventoryBlock bagBlock = new BloodInventoryResultVo.BloodInventoryBlock();
            bagBlock.setBloodType(bloodType);
            bagBlock.setSpecRows(bagRows);
            bagBlock.setSubtotal(bagSubtotalMap);
            bagBlock.setAmount(bagTotalAmount);
            bagBlock.setComponentSubtotal(bagSubtotalMap.values().stream().mapToInt(i -> i).sum());
            bagList.add(bagBlock);
        }

        BloodInventoryResultVo vo = new BloodInventoryResultVo();
        vo.setQuantityList(quantityList);
        vo.setBagList(bagList);
        return vo;
    }

    @Override
    public int cascadeDelete(BloodDeleteReturnVo vo) {
        List<String> bloodIds = vo.getBloodIds();
        String applyId = vo.getApplyId();
        String applyName = vo.getApplyName();
        // 1. 查询要删除的血液信息记录
        LambdaQueryWrapper<BloodInformationEntity> infoQuery = new LambdaQueryWrapper<>();
        infoQuery.in(BloodInformationEntity::getBloodId, bloodIds);
        List<BloodInformationEntity> infoList = bloodInformationDao.selectList(infoQuery);

        // 2. 生成当天最大退血单号
        String returnPrefix = ConstantData.BLOOD_RETURN_NO_WORK_ID; // 或 ConstantData.APPLICATION_NO_PREFIX
        String dateStr = new java.text.SimpleDateFormat("yyyyMMdd").format(new java.util.Date());
        QueryWrapper<BloodReturnEntity> returnWrapper = new QueryWrapper<>();
        returnWrapper.likeRight("blood_return_id", returnPrefix + dateStr);
        returnWrapper.orderByDesc("blood_return_id");
        returnWrapper.last("limit 1");
        BloodReturnEntity maxReturnEntity = bloodReturnDao.selectOne(returnWrapper);

        int nextReturnSeq = 1;
        if (maxReturnEntity != null && maxReturnEntity.getBloodReturnId() != null) {
            String maxNo = maxReturnEntity.getBloodReturnId();
            if (maxNo.length() >= (returnPrefix.length() + 8 + 4)) {
                String seqStr = maxNo.substring(returnPrefix.length() + 8, returnPrefix.length() + 8 + 4);
                nextReturnSeq = Integer.parseInt(seqStr) + 1;
            }
        }

        // 3. 构造并插入退血记录（去重）
        for (BloodInformationEntity info : infoList) {
            // 判断该 bloodId 是否已存在退血记录
            LambdaQueryWrapper<BloodReturnEntity> existQuery = new LambdaQueryWrapper<>();
            existQuery.eq(BloodReturnEntity::getBloodId, info.getBloodId());
            existQuery.eq(BloodReturnEntity::getIsDeleted, 0); // 只查未删除的
            Integer count = bloodReturnDao.selectCount(existQuery);
            if (count != null && count > 0) {
                continue; // 已有退血记录，跳过
            }

            BloodReturnEntity returnEntity = new BloodReturnEntity();
            BeanUtils.copyProperties(info, returnEntity);

            // 生成唯一退血单号
            String returnSeqStr = String.format("%04d", nextReturnSeq++);
            String bloodReturnId = returnPrefix + dateStr + returnSeqStr;
            returnEntity.setBloodReturnId(bloodReturnId);

            // 设置退血人
            returnEntity.setApplyId(applyId);
            returnEntity.setApplyName(applyName);

            // 设置退血原因和审核状态
            returnEntity.setReason(BloodReturnReasonEnum.DELETE_BLOOD_DATA.code());
            returnEntity.setReview(BloodReturnVerifyStateEnum.PASS.code());

            bloodReturnDao.insert(returnEntity);
        }

        // 4. 删除血液信息和入库表
        int informationDeleted = bloodInformationDao.delete(infoQuery);

        LambdaQueryWrapper<BloodInStorgeEntity> storgeQuery = new LambdaQueryWrapper<>();
        storgeQuery.in(BloodInStorgeEntity::getBloodId, bloodIds);
        int storageDeleted = bloodInStorgeDao.delete(storgeQuery);

        return storageDeleted + informationDeleted;
    }

    @Override
    public List<BloodInformationEntity> allSelectedIds(Set<String> bloodIdSet) {
            if (bloodIdSet == null || bloodIdSet.isEmpty()) {
                return Collections.emptyList();
            }
            LambdaQueryWrapper<BloodInformationEntity> queryWrapper = Wrappers.lambdaQuery(BloodInformationEntity.class)
                    .in(BloodInformationEntity::getBloodId, bloodIdSet);
            return this.list(queryWrapper);
    }

}
